/*
 * Copyright (C) 2024, Ingenic Semiconductor Co.,Ltd.
 * Author: Keven <keven.ywhan@ingenic.com>
 */

#ifndef __SFC_BOOT_H
#define __SFC_BOOT_H

#define	SFC_GLB0		0x0000
#define	SFC_DEV_CONF		0x0004
#define	SFC_DEV_STA_EXP		0x0008
#define	SFC_DEV_STA_RT		0x000c
#define	SFC_DEV_STA_MSK		0x0010
#define	SFC_TRAN_CONF0(n)	0x0014 + (n * 4)
#define	SFC_TRAN_LEN		0x002c
#define	SFC_DEV_ADDR(n)		0x0030 + (n * 4)
#define	SFC_DEV_ADDR_PLUS(n)	0x0048 + (n * 4)
#define	SFC_MEM_ADDR		0x0060
#define	SFC_TRIG		0x0064
#define	SFC_SR			0x0068
#define	SFC_SCR			0x006c
#define	SFC_INTC		0x0070
#define	SFC_FSM			0x0074
#define	SFC_CGE			0x0078
#define SFC_GLB1		0x0094
#define	SFC_TRAN_CONF1(n)	0x009c + (n * 4)
#define	SFC_RM_DR		0x1000


//For SFC_GLB0
#define DES_EN                  (1 << 15)
#define CDT_EN                  (1 << 14)
#define	TRAN_DIR		(1 << 13)
#define	THRESHOLD_OFFSET	(7)
#define THRESHOLD_MSK		(0x3f << THRESHOLD_OFFSET)
#define OP_MODE			(1 << 6)
#define PHASE_NUM_OFFSET	(3)
#define PHASE_NUM_MSK		(0x7 << PHASE_NUM_OFFSET)
#define WP_EN			(1 << 2)
#define BURST_MD_OFFSET		(0)
#define BURST_MD_MSK		(0x3 << BURST_MD_OFFSET)

//For SFC_GLB1
#define DQS_EN                  (1 << 2)
#define CHIP_SEL_OFFSET         (0)
#define CHIP_SEL_MSK            (3 << CHIP_SEL_OFFSET)

//For SFC_DEV_CONF
#define STA_ENDIAN              (31)
#define SMP_DELAY_OFFSET        (16)
#define SMP_DELAY_MSK           (0x1f << SMP_DELAY_OFFSET)
#define CMD_TYPE                (1 << 15)
#define STA_TYPE_OFFSET         (13)
#define STA_TYPE_MSK            (3 << STA_TYPE_OFFSET)
#define THOLD_OFFSET            (11)
#define THOLD_MSK               (0x3 << THOLD_OFFSET)
#define TSETUP_OFFSET           (9)
#define TSETUP_MSK              (0x3 << TSETUP_OFFSET)
#define TSH_OFFSET              (5)
#define TSH_MSK                 (0xf << TSH_OFFSET)
#define CPHA                    (1 << 4)
#define CPOL                    (1 << 3)
#define CEDL                    (1 << 2)
#define HOLDDL                  (1 << 1)
#define WPDL                    (1 << 0)

//For SFC_TRAN_CONF0
#define	CLK_MODE_OFFSET	(29)
#define	CLK_MODE_MSK		(0x7 << TRAN_MODE_OFFSET)
#define	ADDR_WIDTH_OFFSET	(26)
#define	ADDR_WIDTH_MSK		(0x7 << ADDR_WIDTH_OFFSET)
#define POLLEN			(1 << 25)
#define CMDEN			(1 << 24)
#define FMAT			(1 << 23)
#define DMYBITS_OFFSET		(17)
#define DMYBITS_MSK		(0x3f << DMYBITS_OFFSET)
#define DATEEN			(1 << 16)
#define	CMD_OFFSET		(0)
#define	CMD_MSK			(0xffff << CMD_OFFSET)

//For SFC_TRAN_CONF1
#define DATA_ENDIAN		(1 << 18)
#define WORD_UNIT_OFFSET	(16)
#define WORD_UNIT_MSK		(3 << WORD_UNIT_OFFSET)
#define	TRAN_MODE_OFFSET	(4)
#define	TRAN_MODE_MSK		(0xf << TRAN_MODE_OFFSET)


//For SFC_TRIG
#define FLUSH			(1 << 2)
#define STOP			(1 << 1)
#define START			(1 << 0)

//For SFC_SR
#define FIFONUM_OFFSET		(16)
#define FIFONUM_MSK		(0x7f << FIFONUM_OFFSET)
#define BUSY_OFFSET		(5)
#define BUSY_MSK		(0x3 << BUSY_OFFSET)
#define END			(1 << 4)
#define TRAN_REQ		(1 << 3)
#define RECE_REQ		(1 << 2)
#define OVER			(1 << 1)
#define UNDER			(1 << 0)

//For SFC_SCR and INTC
#define	END_BIT			(1 << 4)
#define TREQ_BIT		(1 << 3)
#define RREQ_BIT		(1 << 2)
#define OVER_BIT		(1 << 1)
#define UNDER_BIT		(1 << 0)

//For SFC_FSM
#define FSM_AHB_OFFSET		(16)
#define FSM_AHB_MSK		(0xf << FSM_AHB_OFFSET)
#define FSM_SPI_OFFSET		(8)
#define FSM_SPI_MSK		(0xff << FSM_SPI_OFFSET)
#define FSM_DMAC_OFFSET		(4)
#define FSM_DMAC_MSK		(0x7 << FSM_DMAC_OFFSET)
#define FSM_RMC_OFFSET		(0)
#define FSM_RMC_MSK		(0x7 << FSM_RMC_OFFSET)

//For SFC_CGE
#define CG_EN			(1 << 0)

//For SPI NAND flash get feature
#define SPINAND_IS_BUSY  (0x1 << 0)

#define SFC_FIFO_LEN	(63)
#define THRESHOLD	(32)


void sfc_init();
int sfc_block_read(unsigned int start_block, unsigned int block_cnt, void *buf);

#endif /* __SFC_BOOT_H */
